{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 导入必要包\n",
    "import time\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "import scipy.spatial.distance as ssd\n",
    "import pickle"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>user</th>\n",
       "      <th>song</th>\n",
       "      <th>play_count_total_x</th>\n",
       "      <th>score</th>\n",
       "      <th>play_count_total_y</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <td>37078</td>\n",
       "      <td>e6e0f68e948d7bcbf2ed9c4506a40a139a5e7bc7</td>\n",
       "      <td>SOYYKLS12A8C134802</td>\n",
       "      <td>681</td>\n",
       "      <td>0.002937</td>\n",
       "      <td>681</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>32150</td>\n",
       "      <td>a18aa09c5b8a1c03d03cdf6d8eb11c2bf5b907cd</td>\n",
       "      <td>SOXQYSC12A6310E908</td>\n",
       "      <td>807</td>\n",
       "      <td>0.003717</td>\n",
       "      <td>807</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>2893</td>\n",
       "      <td>da3890400751de76f0f05ef0e93aa1cd898e7dbc</td>\n",
       "      <td>SOIROON12A6701E0B8</td>\n",
       "      <td>592</td>\n",
       "      <td>0.003378</td>\n",
       "      <td>592</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>14124</td>\n",
       "      <td>d04eed168e8e31d9d05cfca98cf08a3abf7bd9f4</td>\n",
       "      <td>SOPJLFV12A6701C797</td>\n",
       "      <td>487</td>\n",
       "      <td>0.006160</td>\n",
       "      <td>487</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>13014</td>\n",
       "      <td>a41d3edbc2798b6800fe15845a979150eb244b85</td>\n",
       "      <td>SOHFJAQ12AB017E4AF</td>\n",
       "      <td>956</td>\n",
       "      <td>0.002092</td>\n",
       "      <td>956</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                                           user                song  \\\n",
       "37078  e6e0f68e948d7bcbf2ed9c4506a40a139a5e7bc7  SOYYKLS12A8C134802   \n",
       "32150  a18aa09c5b8a1c03d03cdf6d8eb11c2bf5b907cd  SOXQYSC12A6310E908   \n",
       "2893   da3890400751de76f0f05ef0e93aa1cd898e7dbc  SOIROON12A6701E0B8   \n",
       "14124  d04eed168e8e31d9d05cfca98cf08a3abf7bd9f4  SOPJLFV12A6701C797   \n",
       "13014  a41d3edbc2798b6800fe15845a979150eb244b85  SOHFJAQ12AB017E4AF   \n",
       "\n",
       "       play_count_total_x     score  play_count_total_y  \n",
       "37078                 681  0.002937                 681  \n",
       "32150                 807  0.003717                 807  \n",
       "2893                  592  0.003378                 592  \n",
       "14124                 487  0.006160                 487  \n",
       "13014                 956  0.002092                 956  "
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#读取训练数据集\n",
    "df_train=pd.read_csv('triplet_dataset_sub_train.csv',index_col=0)\n",
    "df_train.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "#读取训练集用户-歌曲，歌曲-用户索引表,用户-歌曲打分矩阵\n",
    "user_item_dict=pickle.load(open('user_item_dict.pkl','rb'))\n",
    "item_user_dict=pickle.load(open('item_user_dict.pkl','rb'))\n",
    "user_item_score=pickle.load(open('user_item_score.pkl','rb'))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 计算相似度\n",
    "使用皮尔逊相关系数计算用户之间的相似度"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "#计算用户的平均打分\n",
    "user_score_mean=df_train[['user','score']].groupby('user').mean().reset_index()\n",
    "\n",
    "#转化为字典，方便后面计算\n",
    "user_score_mean_dict={}\n",
    "for line in user_score_mean.index:\n",
    "    user_score_mean_dict[user_score_mean.iloc[line]['user']]=user_score_mean.iloc[line]['score']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "#定义相似度函数\n",
    "def similarity_user(uid1,uid2):\n",
    "    item_both=[]\n",
    "    \n",
    "    #筛选两个用户都听过的歌曲\n",
    "    for i in user_item_dict[uid1]:\n",
    "        if i in user_item_dict[uid2]:\n",
    "            item_both.append(i)\n",
    "    \n",
    "    #如果两用户听过歌曲交集为空，则令相似度为0\n",
    "    if len(item_both)==0:\n",
    "        similarity=0\n",
    "        return similarity\n",
    "    \n",
    "    #两用户的特征表示\n",
    "    uid1_score= [user_item_score.loc[uid1][i]-user_score_mean_dict[uid1] for i in item_both]\n",
    "    uid2_score= [user_item_score.loc[uid2][i]-user_score_mean_dict[uid2] for i in item_both]\n",
    "    \n",
    "    #求两用户的皮尔逊相关系数\n",
    "    similarity=1-ssd.cosine(uid1_score,uid2_score)\n",
    "    \n",
    "    if np.isnan(similarity):\n",
    "        similarity=0\n",
    "    \n",
    "    return similarity"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/opt/anaconda3/lib/python3.7/site-packages/ipykernel_launcher.py:1: DeprecationWarning: time.clock has been deprecated in Python 3.3 and will be removed from Python 3.8: use time.perf_counter or time.process_time instead\n",
      "  \"\"\"Entry point for launching an IPython kernel.\n",
      "/opt/anaconda3/lib/python3.7/site-packages/scipy/spatial/distance.py:720: RuntimeWarning: invalid value encountered in double_scalars\n",
      "  dist = 1.0 - uv / np.sqrt(uu * vv)\n",
      "/opt/anaconda3/lib/python3.7/site-packages/ipykernel_launcher.py:13: DeprecationWarning: time.clock has been deprecated in Python 3.3 and will be removed from Python 3.8: use time.perf_counter or time.process_time instead\n",
      "  del sys.path[0]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "total time: 378.891669\n"
     ]
    }
   ],
   "source": [
    "star=time.clock()\n",
    "\n",
    "#预先计算所有用户相似度\n",
    "similarity_users=pd.DataFrame(index=df_train['user'].unique(),columns=df_train['user'].unique())\n",
    "\n",
    "for u1 in df_train['user'].unique():\n",
    "    for u2 in df_train['user'].unique():\n",
    "        if u2==u1:\n",
    "            similarity_users.loc[u1][u2]=1\n",
    "        else:\n",
    "            similarity_users.loc[u1][u2]=similarity_user(u1,u2)\n",
    "\n",
    "end=time.clock()\n",
    "print('total time:',end-star)\n",
    "\n",
    "\n",
    "#保存用户相似度\n",
    "pickle.dump(similarity_users,open('similarity_users.pkl','wb'))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 预测打分并推荐\n",
    "1. 找到用户未打过分的歌曲\n",
    "2. 找到此批歌曲其他打过分的用户及打分\n",
    "3. 根据相似度及分数预测打分\n",
    "4. 推荐前N个分数最高物品"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "#定义推荐函数\n",
    "def User_CF_recommend_items(uid,n_item):\n",
    "    \n",
    "    #初始化推荐歌曲-分数字典\n",
    "    recommend_scores={}\n",
    "    for i in df_train['song'].unique():\n",
    "        if i not in user_item_dict[uid]:\n",
    "            for u in item_user_dict[i]:\n",
    "                \n",
    "                #预测的打分=本用户平均打分+相似度*打分\n",
    "                recommend_score=user_score_mean_dict[uid]+similarity_users.loc[uid][u]*user_item_score.loc[u][i]\n",
    "                \n",
    "            recommend_scores[i]=recommend_score\n",
    "            \n",
    "    #将recommend_scores转化为dataframe，并按降序排列\n",
    "    recommend_scores=pd.DataFrame.from_dict(recommend_scores, orient='index', columns=['values']).reset_index()\n",
    "    recommend_scores=recommend_scores.rename(columns={'index':'recommend_song','values':'recommend_score'})\n",
    "    recommend_scores=recommend_scores.sort_values(by='recommend_score',ascending=False)\n",
    "    \n",
    "    recommend_item=recommend_scores[0:n_item]\n",
    "    \n",
    "    return recommend_item"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 测试（性能评估）\n",
    "选择评估指标（精确率、召回率、覆盖率）  \n",
    "\n",
    "\n",
    "\n",
    "令系统的用户集合为 U， R(u) 是根据用户在训练集上的行为给用户作出的推荐列表，而 T(u) 是用户在测试集上的行为列表。  \n",
    "推荐结果的精确率定义为：\n",
    "$$\n",
    "Precision=\\frac{\\sum_{u\\in U}|R(u)\\cap T(u)|}{\\sum_{u\\in U}|R(u)|}\n",
    "$$\n",
    "推荐结果的召回率定义为：\n",
    "$$\n",
    "Recall=\\frac{\\sum_{u\\in U}|R(u)\\cap T(u)|}{\\sum_{u\\in U}|T(u)|}\n",
    "$$\n",
    "\n",
    "推荐系统的覆盖率为：\n",
    "$$\n",
    "Coverage=\\frac{\\sum_{u\\in U}|R(u)|}{|I|}\n",
    "$$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>user</th>\n",
       "      <th>song</th>\n",
       "      <th>play_count_total_x</th>\n",
       "      <th>score</th>\n",
       "      <th>play_count_total_y</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <td>15824</td>\n",
       "      <td>119b7c88d58d0c6eb051365c103da5caf817bea6</td>\n",
       "      <td>SOEQJBS12A8AE475A4</td>\n",
       "      <td>2477</td>\n",
       "      <td>0.002422</td>\n",
       "      <td>2477</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>7599</td>\n",
       "      <td>8b2f76211d04fa0f91b9f0c8134064b2968882c2</td>\n",
       "      <td>SOYRAHL12A6310D821</td>\n",
       "      <td>684</td>\n",
       "      <td>0.073099</td>\n",
       "      <td>684</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>7954</td>\n",
       "      <td>7bdfc45af7e15511d150e2acb798cd5e4788abf5</td>\n",
       "      <td>SOSCDWE12AB01823C4</td>\n",
       "      <td>523</td>\n",
       "      <td>0.028681</td>\n",
       "      <td>523</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>25905</td>\n",
       "      <td>7d4736c0c05264716e87d7fc825a535e0a01ba6d</td>\n",
       "      <td>SOJEVHC12A8C13C3E5</td>\n",
       "      <td>140</td>\n",
       "      <td>0.014286</td>\n",
       "      <td>140</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>35108</td>\n",
       "      <td>954469357b2434a20c76e940eca93185141b7f9b</td>\n",
       "      <td>SOXKDFJ12A6D4FA8F9</td>\n",
       "      <td>307</td>\n",
       "      <td>0.006515</td>\n",
       "      <td>307</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                                           user                song  \\\n",
       "15824  119b7c88d58d0c6eb051365c103da5caf817bea6  SOEQJBS12A8AE475A4   \n",
       "7599   8b2f76211d04fa0f91b9f0c8134064b2968882c2  SOYRAHL12A6310D821   \n",
       "7954   7bdfc45af7e15511d150e2acb798cd5e4788abf5  SOSCDWE12AB01823C4   \n",
       "25905  7d4736c0c05264716e87d7fc825a535e0a01ba6d  SOJEVHC12A8C13C3E5   \n",
       "35108  954469357b2434a20c76e940eca93185141b7f9b  SOXKDFJ12A6D4FA8F9   \n",
       "\n",
       "       play_count_total_x     score  play_count_total_y  \n",
       "15824                2477  0.002422                2477  \n",
       "7599                  684  0.073099                 684  \n",
       "7954                  523  0.028681                 523  \n",
       "25905                 140  0.014286                 140  \n",
       "35108                 307  0.006515                 307  "
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 读取测试集数据\n",
    "df_test=pd.read_csv('triplet_dataset_sub_test.csv',index_col=0)\n",
    "df_test.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "#读取测试集上用户-歌曲索引表\n",
    "user_item_test_dict=pickle.load(open('user_item_test_dict.pkl','rb'))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "1/\\推荐10首歌曲n_recommend = 10"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/opt/anaconda3/lib/python3.7/site-packages/ipykernel_launcher.py:1: DeprecationWarning: time.clock has been deprecated in Python 3.3 and will be removed from Python 3.8: use time.perf_counter or time.process_time instead\n",
      "  \"\"\"Entry point for launching an IPython kernel.\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "3b4bb393138bba331e3dde43dfdc05554f05a743 is new user\n",
      "af3ee32357049dd96231238bd1b019e8142ee6aa is new user\n",
      "6a58f480d522814c087fd3f8c77b3f32bb161f9d is new user\n",
      "7875303e731b91b046ec6fbcd640e0b7d8499753 is new user\n",
      "9d17a429365653228049e8fe3d5968d4cd5dc6fe is new user\n",
      "467e0e46181933c7e1a936e513ca55fbab4edaed is new user\n",
      "e504626e4d38404e3928bda4b0f266cbd38c42d8 is new user\n",
      "total time: 3349.764758\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/opt/anaconda3/lib/python3.7/site-packages/ipykernel_launcher.py:52: DeprecationWarning: time.clock has been deprecated in Python 3.3 and will be removed from Python 3.8: use time.perf_counter or time.process_time instead\n"
     ]
    }
   ],
   "source": [
    "star=time.clock()\n",
    "\n",
    "#初始化变量\n",
    "\n",
    "#推荐歌曲数目\n",
    "n_recommend=10\n",
    "\n",
    "#推荐的歌曲中玩家会播放的歌曲数量\n",
    "n_hit=0\n",
    "\n",
    "#总共推荐的次数\n",
    "total_recommend=0\n",
    "\n",
    "#推荐的歌曲数量\n",
    "total_recommend_unique=set()\n",
    "#rss_test=0\n",
    "\n",
    "#遍历测试集中每一位用户\n",
    "for u in df_test['user'].unique():\n",
    "    \n",
    "    #打印出新用户\n",
    "    if u not in df_train['user'].unique():\n",
    "        print(u,'is new user')\n",
    "        continue\n",
    "        \n",
    "    recommend_items=User_CF_recommend_items(u,n_recommend)\n",
    "    \n",
    "    #遍历没首推荐歌曲，判断并找出推荐命中的歌曲\n",
    "    for recommend_i in recommend_items[recommend_items.columns[0]]:\n",
    "        if recommend_i in user_item_test_dict[u]:\n",
    "            n_hit=n_hit+1\n",
    "        total_recommend_unique.add(recommend_i) \n",
    "    \n",
    "        #计算mse\n",
    "        #score_pre=user_item_score.loc[u][recommend_i]\n",
    "        #score_test=user_item_test_score.loc[u][recommend_i]\n",
    "        #rss_test=rss_test+(score_pre-score_test)**2\n",
    "        \n",
    "        \n",
    "    total_recommend=total_recommend+n_recommend\n",
    "            \n",
    "#精确率          \n",
    "precision=n_hit/total_recommend\n",
    "\n",
    "#召回率\n",
    "recall=n_hit/len(df_test['song'])\n",
    "\n",
    "#覆盖率\n",
    "coverage=len(total_recommend_unique)/len(df_train['song'].unique())\n",
    "#rmse=np.sqrt(rss_test/len(df_test['song']))\n",
    "\n",
    "end=time.clock()\n",
    "print('total time:',end-star)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "10"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "n_recommend"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.018715846994535518"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "precision"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.01825692963752665"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "recall"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.25"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "coverage"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "2. 推荐20首歌曲 n_recommend=20"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/opt/anaconda3/lib/python3.7/site-packages/ipykernel_launcher.py:1: DeprecationWarning: time.clock has been deprecated in Python 3.3 and will be removed from Python 3.8: use time.perf_counter or time.process_time instead\n",
      "  \"\"\"Entry point for launching an IPython kernel.\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "3b4bb393138bba331e3dde43dfdc05554f05a743 is new user\n",
      "af3ee32357049dd96231238bd1b019e8142ee6aa is new user\n",
      "6a58f480d522814c087fd3f8c77b3f32bb161f9d is new user\n",
      "7875303e731b91b046ec6fbcd640e0b7d8499753 is new user\n",
      "9d17a429365653228049e8fe3d5968d4cd5dc6fe is new user\n",
      "467e0e46181933c7e1a936e513ca55fbab4edaed is new user\n",
      "e504626e4d38404e3928bda4b0f266cbd38c42d8 is new user\n",
      "total time: 3311.604211\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/opt/anaconda3/lib/python3.7/site-packages/ipykernel_launcher.py:50: DeprecationWarning: time.clock has been deprecated in Python 3.3 and will be removed from Python 3.8: use time.perf_counter or time.process_time instead\n"
     ]
    }
   ],
   "source": [
    "star=time.clock()\n",
    "\n",
    "#初始化变量\n",
    "\n",
    "#推荐歌曲数目\n",
    "n_recommend=20\n",
    "#推荐的歌曲中玩家会播放的歌曲数量\n",
    "n_hit=0\n",
    "#总共推荐的次数\n",
    "total_recommend=0\n",
    "#推荐的歌曲数量\n",
    "total_recommend_unique=set()\n",
    "\n",
    "#rss_test=0\n",
    "\n",
    "#遍历测试集中每一位用户\n",
    "for u in df_test['user'].unique():\n",
    "    \n",
    "    #打印出新用户\n",
    "    if u not in df_train['user'].unique():\n",
    "        print(u,'is new user')\n",
    "        continue\n",
    "        \n",
    "    recommend_items=User_CF_recommend_items(u,n_recommend)\n",
    "    \n",
    "    #判断并找出推荐命中的歌曲\n",
    "    for recommend_i in recommend_items[recommend_items.columns[0]]:\n",
    "        if recommend_i in user_item_test_dict[u]:\n",
    "            n_hit=n_hit+1\n",
    "        total_recommend_unique.add(recommend_i) \n",
    "    \n",
    "        #计算mse\n",
    "        #score_pre=user_item_score.loc[u][recommend_i]\n",
    "        #score_test=user_item_test_score.loc[u][recommend_i]\n",
    "        #rss_test=rss_test+(score_pre-score_test)**2\n",
    "        \n",
    "        \n",
    "    total_recommend=total_recommend+n_recommend\n",
    "            \n",
    "#精确率          \n",
    "precision=n_hit/total_recommend\n",
    "\n",
    "#召回率\n",
    "recall=n_hit/len(df_test['song'])\n",
    "\n",
    "#覆盖率\n",
    "coverage=len(total_recommend_unique)/len(df_train['song'].unique())\n",
    "#rmse=np.sqrt(rss_test/len(df_test['song']))\n",
    "\n",
    "end=time.clock()\n",
    "print('total time:',end-star)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "20"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "n_recommend"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.015846994535519125"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "precision"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.03091684434968017"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "recall"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.41875"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "coverage"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
